package com.koron.housing.info.service.impl;


import com.github.pagehelper.PageInfo;
import com.koron.bean.query.PageQuery;
import com.koron.common.core.business.configsettings.utils.ConfigInfoTool;
import com.koron.common.core.business.message.bean.po.MessageTemplatePo;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.message.MessageUtil;
import com.koron.common.task.web.entity.CronTask;
import com.koron.housing.admin.bean.po.HousingAdmin;
import com.koron.housing.admin.service.HousingAdminService;
import com.koron.housing.apply.bean.query.HousingApplyQuery;
import com.koron.housing.apply.bean.vo.HousingStaffApplyVO;
import com.koron.housing.apply.service.HousingStaffApplyService;
import com.koron.housing.info.bean.dto.HousingInfoDTO;
import com.koron.housing.info.bean.dto.HousingInfoTree;
import com.koron.housing.info.bean.po.HousingInfo;
import com.koron.housing.info.bean.po.HousingRecord;
import com.koron.housing.info.bean.query.HousingInfoQuery;
import com.koron.housing.info.bean.vo.HousingInfoVO;
import com.koron.housing.info.mapper.HousingInfoMapper;
import com.koron.housing.info.service.HousingInfoService;
import com.koron.housing.info.service.HousingRecordService;
import com.koron.housing.staff.bean.po.HousingLease;
import com.koron.housing.staff.bean.query.HousingStaffQuery;
import com.koron.housing.staff.bean.vo.HousingStaffVO;
import com.koron.housing.staff.service.HousingLeaseService;
import com.koron.housing.staff.service.HousingStaffService;
import com.koron.housing.util.DelayUtils;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.apache.commons.lang.time.DateFormatUtils;
import org.koron.ebs.mybatis.ADOConnection;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 房源台账(HousingInfo)表服务实现类
 *
 * @author jzp
 * @since 2022-02-25 15:16:32
 */
@Service("infoService")
public class HousingInfoServiceImpl implements HousingInfoService {

    @Autowired
    private HousingLeaseService leaseService;
    @Autowired
    private HousingStaffService staffService;
    @Autowired
    private HousingStaffApplyService applyService;
    @Autowired
    private HousingAdminService adminService;
    @Autowired
    private HousingRecordService recordService;
    @Autowired
    private MessageUtil messageUtil;
    private String getCurrDs() {
        return ThreadLocalContext.get().getCurrDs();
    }

    /**
     * 通过ID查询单条数据
     */
    @Override
    @TaskAnnotation("getById")
    public HousingInfo getById(SessionFactory factory, String id) {
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return mapper.selectById(id);
    }

    /**
     * 查询所有数据
     */
    @Override
    @TaskAnnotation("list")
    public List<HousingInfo> list(SessionFactory factory, HousingInfoQuery query) {
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return mapper.selectList(query);
    }

    @Override
    @TaskAnnotation("listDto")
    public List<HousingInfoDTO> listDto(SessionFactory factory, HousingInfoQuery query) {
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return mapper.selectDtoList(query);
    }

    @Override
    @TaskAnnotation("listVo")
    public List<HousingInfoVO> listVo(SessionFactory factory, HousingInfoQuery query) {
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return mapper.selectVoList(query);
    }

    @Override
    @TaskAnnotation("listByContractId")
    public List<HousingInfo> listByContractId(SessionFactory factory, String contractId) {
        HousingInfoQuery housingInfoQuery = new HousingInfoQuery();
        housingInfoQuery.setContractId(contractId);
        return list(factory, housingInfoQuery);
    }

    @Override
    @TaskAnnotation("page")
    public PageInfo<HousingInfoVO> page(SessionFactory factory, PageQuery pageQuery, HousingInfoQuery query) {
        pageQuery.prefixOrders("housingInfo", null);
        return HousingInfoService.super.page(factory, pageQuery, query);
    }

    @Override
    @TaskAnnotation("tree")
    public List<HousingInfoTree> tree(SessionFactory factory) {
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return mapper.selectTree();
    }

    @Override
    @TaskAnnotation("address")
    public List<HousingInfo> address(SessionFactory factory, String propertySource) {
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return mapper.address(propertySource);
    }

    @Override
    @TaskAnnotation("village")
    public List<HousingInfo> village(SessionFactory factory, String propertySource) {
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return mapper.village(propertySource);
    }

    @Override
    @TaskAnnotation("hasExpiredHouse")
    public List<Boolean> hasExpiredHouse(SessionFactory factory) {
        // 只有过渡房管理人员可以查看所有过渡房数据以及接收框架合同到期提醒
        List<HousingAdmin> housingAdmins = adminService.listHousingAdmin(factory);
        long count = housingAdmins.stream().filter(e -> "1".equals(e.getType())).count();
        if (count == 0) {
            return null;
        }
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return Arrays.asList(mapper.selectGroupFrameDate() > 0, mapper.selectGroupLeaseDate() > 0);
    }

    @Override
    @TaskAnnotation("topic")
    public String topic(SessionFactory factory) {
        // 查询闲置的人才房数量
        HousingInfoQuery query = new HousingInfoQuery();
        query.setStatus(Collections.singletonList("0"));
        query.setPropertySource(Collections.singletonList("1"));
        List<HousingInfo> list = list(factory, query);
        int count = CollectionUtils.isEmpty(list) ? 0 : list.size();
        if (count == 0) {
            return "暂无闲置房源";
        }
        Map<String, String> config = ConfigInfoTool.getConfigByCode("housing", "housing_topic_info");
        String datadiff = config.get("datadiff");
        // 获取秒
        Date topicDate = new Date(new Date().getTime() + Integer.parseInt(datadiff) * 24 * 60 * 60L);
        String format = DateFormatUtils.format(topicDate, "yyyy-MM-dd");
        List<MessageTemplatePo> templatePoList = messageUtil.getTemplate("housing_info_topic");
        // 只拿企业微信的模板
        String template = templatePoList.stream().filter(e -> "qywx".equals(e.getNotifyType())).map(MessageTemplatePo::getTemplate).findFirst().orElse("");
        // %s间套房1，%s间单间0，截止登记日期为：%s
        return String.format(template,
                list.stream().filter(e -> "1".equals(e.getType())).count(),
                list.stream().filter(e -> "0".equals(e.getType())).count(),
                format);
    }

    /**
     * 发布房源通知时，自动将闲置的套房发送给申请套房的人、将闲置的单间发送给申请单间的人
     */
    @Override
    @TaskAnnotation("sendMessage")
    public void sendMessage(SessionFactory factory, String message) {
        // 找发送的人 查询所有未入住0的租户，且需求申请2已结束
        HousingStaffQuery staffQuery = new HousingStaffQuery();
        staffQuery.setStatus(Collections.singletonList("0"));
        List<String> list1 = Optional.ofNullable(staffService
                        .list(factory, staffQuery))
                .map(e -> e.stream()
                        .map(HousingStaffVO::getAccount)
                        .distinct()
                        .collect(Collectors.toList()))
                .orElse(new ArrayList<>());

        HousingApplyQuery applyQuery = new HousingApplyQuery();
        applyQuery.setPropertySource("1");
        applyQuery.setStatus(Collections.singletonList("2"));
        List<String> list2 = Optional.ofNullable(applyService
                .list(factory, applyQuery))
                .map(e -> e.stream()
                        .map(HousingStaffApplyVO::getAccount)
                        .distinct()
                        .collect(Collectors.toList()))
                .orElse(new ArrayList<>());
        String accounts = list1.stream().filter(list2::contains).collect(Collectors.joining(","));
        messageUtil.sendQywxText(accounts, message);
    }

    @XxlJob(value = "sendFrameMessage")
    public void sendFrameMessage() {
        CronTask cronTask = DelayUtils.getCurrTask();

        // 获取房源id
        String id = Optional.ofNullable(cronTask.getBusinessId())
                .map(str -> str.split("Frame"))
                .filter(arr -> arr.length > 0)
                .map(arr -> arr[0])
                .orElseThrow(() -> new IllegalArgumentException("id不能未空"));

        HousingInfo housingInfo = ADOConnection.runTask(cronTask.getMark(), this, "getById", HousingInfo.class, id);
        // 给过渡房管理员发送消息
        List<HousingAdmin> housingAdmins = ADOConnection.runTask(cronTask.getMark(), adminService, "listHousingAdmin", List.class);
        messageUtil.sendQywxText(housingAdmins.stream().filter(e -> "1".equals(e.getType())).map(HousingAdmin::getAccount).distinct().collect(Collectors.joining(",")), "您负责的房源框架合同还剩3个月到期，请及时关注：" + housingInfo.getVillage() + housingInfo.getAddress() + housingInfo.getRoomNum());
    }

    @XxlJob(value = "sendLeaseMessage")
    public void sendLeaseMessage() {
        CronTask cronTask = DelayUtils.getCurrTask();

        // 获取房源id
        String id = Optional.ofNullable(cronTask.getBusinessId())
                .map(str -> str.split("Lease"))
                .filter(arr -> arr.length > 0)
                .map(arr -> arr[0])
                .orElseThrow(() -> new IllegalArgumentException("id不能未空"));

        HousingInfo housingInfo = ADOConnection.runTask(cronTask.getMark(), this, "getById", HousingInfo.class, id);
        // 给过渡房管理员发送消息
        List<HousingAdmin> housingAdmins = ADOConnection.runTask(cronTask.getMark(), adminService, "listHousingAdmin", List.class);
        messageUtil.sendQywxText(housingAdmins.stream().filter(e -> "1".equals(e.getType())).map(HousingAdmin::getAccount).distinct().collect(Collectors.joining(",")), "您负责的租赁合同还剩3个月到期，请及时关注：" + housingInfo.getVillage() + housingInfo.getAddress() + housingInfo.getRoomNum());
        // 给租户发送消息
        List<HousingRecord> housingRecords = ADOConnection.runTask(cronTask.getMark(), recordService, "listByHousingId", List.class, id);
        String collect = housingRecords.stream().filter(e -> e.getOutDate() == null).map(HousingRecord::getAccount).distinct().collect(Collectors.joining(","));
        messageUtil.sendQywxText(collect, "您的租赁合同还剩3个月到期，请及时关注：" + housingInfo.getVillage() + housingInfo.getAddress() + housingInfo.getRoomNum());
    }

    /**
         * 新增数据
         */
    @Override
    @TaskAnnotation("save")
    public boolean save(SessionFactory factory, HousingInfo housingInfo) {
        // 如果没有状态，则为草稿状态
        if (StringUtils.isEmpty(housingInfo.getStatus())) {
            housingInfo.setStatus("0");
        }
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        mapper.insertOrUpdate(housingInfo);
        HousingInfoVO housingInfoVO = mapper.selectVoById(housingInfo.getId());
        // 扣去3个月
        if (housingInfoVO.getFrameEndTime() != null) {
            long frameEndTime = housingInfoVO.getFrameEndTime().getTime() - 3 * 30 * 24 * 60 * 60;
            DelayUtils.putTask(housingInfo.getId()+"Frame", frameEndTime, getCurrDs(), "sendFrameMessage");
        }

        if (housingInfoVO.getLeaseEndTime() != null) {
            long leaseEndTime = housingInfoVO.getLeaseEndTime().getTime() - 3 * 30 * 24 * 60 * 60;
            DelayUtils.putTask(housingInfo.getId()+"Lease", leaseEndTime, getCurrDs(), "sendLeaseMessage");
        }
        return true;
    }

    @Override
    @TaskAnnotation("saveBatch")
    public boolean saveBatch(SessionFactory factory, List<HousingInfo> housingInfoList) {
        if (CollectionUtils.isEmpty(housingInfoList)) {
            return false;
        }
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return mapper.insertOrUpdateBatch(housingInfoList) > 0;
    }

    /**
     * 修改数据
     */
    @Override
    @TaskAnnotation("update")
    public boolean update(SessionFactory factory, HousingInfo housingInfo) {
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return mapper.update(housingInfo) > 0;
    }

    /**
     * 如果租房记录中有已入住的记录，则为已出租
     * 如果为空或全已退租，则为闲置
     */
    @Override
    @TaskAnnotation("autoStatus")
    public boolean autoStatus(SessionFactory factory, String id) {
        // 从租赁信息中查询该房源已入住1的记录
        HousingLease housingLease = new HousingLease();
        housingLease.setHousingId(id);
        housingLease.setStatus("1");
        List<HousingLease> list = leaseService.list(factory, housingLease);
        // 如果为空，则闲置0，否则，已出租1
        String status = "1";
        if (CollectionUtils.isEmpty(list)) {
            status = "0";
        }
        return updateStatus(factory, id, status);
    }

    @Override
    @TaskAnnotation("updateStatus")
    public boolean updateStatus(SessionFactory factory, String id, String status) {
        HousingInfo housingInfo = new HousingInfo();
        housingInfo.setId(id);
        housingInfo.setStatus(status);
        return update(factory, housingInfo);
    }

    /**
     * 通过主键删除数据
     */
    @Override
    @TaskAnnotation("deleteById")
    public boolean deleteById(SessionFactory factory, String id) {
        HousingInfoMapper mapper = factory.getMapper(HousingInfoMapper.class);
        return mapper.hidden(id) > 0;
    }

}
